package com.ehotting.edsta.driverAdapt.controller;

import com.ehotting.eaf.core.StringHelper;
import com.ehotting.eaf.redis.domain.RedisMsgDto;
import com.ehotting.edsta.driverAdapt.config.WebsocketConfigurator;
import com.ehotting.mqbd.api.bean.MqApplicationContext;
import com.ehotting.mqbd.core.manager.AgentLinkManager;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
//@RestController
@Component
@ServerEndpoint(value="/websocket.ws/{userId}/{mainProjectId}", configurator = WebsocketConfigurator.class)
public class DriverAdaptWsController {

    private static Logger logger = LoggerFactory.getLogger(DriverAdaptWsController.class);

    public static ConcurrentHashMap<String, Session> webSocketSet = new ConcurrentHashMap<>();
    public static ConcurrentHashMap<String, String> webSocketIdSet = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<String, Session> getWebSocketSet() {
        return webSocketSet;
    }


    @Autowired
    private MqApplicationContext mqApplicationContext;

    @Autowired
    private AgentLinkManager agentLinkManager;

    /**
     * 连接建立成功调用的方法
     * @param userId
     * @param session
     * @throws Exception
     */
    @OnOpen
    public void onOpen(@PathParam("userId") Long userId,
                       @PathParam("mainProjectId") String mainProjectId,
                       Session session) throws Exception {
        log.info("userId:"+userId+"\tmainProjectId:"+mainProjectId+"\t连接成功");
        String agentId = agentLinkManager.genAgentId(mqApplicationContext.getModule(),userId,mainProjectId);
        sessionPut( session, agentId);
    }

    /**
     * 连接关闭调用方法
     */
    @OnClose
    public void onClose(Session session) {
        log.info("Start close websocket.");
        sessionRemove(session);
        log.info("Finish close websocket.");
    }

    /**
     * 收到客户端消息后调用方法
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) throws Exception{
        if (session.isOpen()) {
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("websocket 发生异常", error);
        sessionRemove(session);
    }



    /**
     * 向客户端发送消息推送
     * @param message
     * @throws Exception
     */
    public void sendMessage(Session session,String message) throws Exception {
        synchronized (session) {
            if (session.isOpen()) {
//                log.info("session.isOpen>>>>>>msg len is {}",message.length());
                session.getBasicRemote().sendText(message);
            }
        }
    }

    /**
     * 向客户端发送消息推送
     * @param redisMsgDto
     * @throws Exception
     */
    public void sendMessage(RedisMsgDto<?> redisMsgDto) throws Exception {
        String userId = redisMsgDto.getUserId()+"";
        log.info("send websocket msg, userId is {}",userId);
        if(webSocketSet.get(userId) != null){
            sendMessage(webSocketSet.get(userId),redisMsgDto.getData().toString());
        }else{
            log.info("当前用户不在线：" + userId);
        }
    }

    /**
     * 发送信息给指定ID用户，如果用户不在线则返回
     * @param message
     * @param sendUserId
     * @throws IOException
     */
    public void sendUserMessage(String message,String sendUserId) throws Exception {

        if(webSocketSet.get(sendUserId) != null){
            logger.info("sendUserId:{},message:{}",sendUserId,message);
            sendMessage(webSocketSet.get(sendUserId),message);
        }else{
            log.info("当前用户不在线：" + sendUserId);
        }
    }


    /**
     * 推送信息给所有用户
     * @param message
     */
    public void sendAllMessage(String message) {
        log.info("推送信息给所有用户>>>>>>>message.length is {}",message.length());

        for(String key : webSocketSet.keySet()){
            try {
                sendMessage(webSocketSet.get(key),message);
            }catch (Exception e){
                log.info("推送信息给所有用户异常：" + e.getMessage());
            }
        }
    }

    private void sessionPut(Session session,String agentId){
        webSocketSet.put(agentId, session);
        webSocketIdSet.put(session.getId(),agentId);
        agentLinkManager.setClientIpAndAgentId(agentId,mqApplicationContext.getLocalHost());
    }

    private void sessionRemove(Session session){
        String agentId = webSocketIdSet.get(session.getId()) ;
        if(StringHelper.hasText(agentId)){
            agentLinkManager.deleteClientIpAndAgentId(agentId);
        }
        webSocketIdSet.remove(session.getId());
        webSocketSet.remove(session);
    }

}